<?php

declare(strict_types=1);

namespace app\middleware;

use app\common\enum\ResponseCode;
use app\common\service\AdminService;
use app\common\utils\JsonResponse;
use think\facade\Request;
use app\common\service\LogService;

class Auth
{
    protected AdminService $adminService;
    protected LogService $logService;

    public function __construct(AdminService $adminService, LogService $logService)
    {
        $this->adminService = $adminService;
        $this->logService = $logService;
    }

    /**
     * 处理请求
     * @param \think\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle($request, \Closure $next)
    {
        // 排除 docs 路径
        if (strpos($request->pathinfo(), 'docs') === 0) {
            return $next($request);
        }

        // 获取 Authorization header
        $token = Request::header('Authorization');

        if (empty($token)) {
            return JsonResponse::error('请先登录', ResponseCode::UNAUTHORIZED);
        }

        // 去掉可能存在的 Bearer 前缀
        $token = str_replace('Bearer ', '', $token);

        try {
            // 验证并解析token
            $tokenInfo = $this->adminService->verifyToken($token);

            if (empty($tokenInfo['admin_id'])) {
                return JsonResponse::error('无效的登录凭证', ResponseCode::UNAUTHORIZED);
            }

            // 获取完整的管理员信息（包含角色和权限）
            $adminInfo = $this->adminService->getAdminInfo($tokenInfo['admin_id']);

            // 将管理员信息存储到请求对象中，方便后续使用
            $request->adminId = $tokenInfo['admin_id'];
            $request->adminInfo = array_merge($adminInfo, [
                'admin_id' => $tokenInfo['admin_id']
            ]);

            $this->logService->setExtend([
                'admin_id' => $tokenInfo['admin_id'],
                'username' => $adminInfo['username'],
                'roles' => $adminInfo['roles']
            ]);
        } catch (\Exception $e) {
            return JsonResponse::error($e->getMessage(), ResponseCode::TOKEN_EXPIRED);
        }

        return $next($request);
    }
}
